<script setup lang="ts">
import { ref, reactive, onMounted, onUnmounted, nextTick } from "vue"

interface CarouselItem {
  id: number
  imageUrl: string
  title?: string
  description?: string
}

const props = defineProps({
  // 轮播图数据
  items: {
    type: Array as () => CarouselItem[],
    required: true,
  },
  // 自动轮播间隔时间（毫秒）
  interval: {
    type: Number,
    default: 5000,
  },
  // 是否显示指示器
  showIndicators: {
    type: Boolean,
    default: true,
  },
  // 是否显示导航按钮
  showNavigation: {
    type: Boolean,
    default: true,
  },
})

const emit = defineEmits(["change"])

// 当前活动项索引
const activeIndex = ref(0)
// 轮播定时器
let timer: number | null = null
// 轮播图容器
const carouselRef = ref<HTMLElement | null>(null)
// 指示器容器
const indicatorsRef = ref<HTMLElement | null>(null)
// 轮播图宽度
const itemWidth = ref(0)
// 是否正在过渡
const isTransitioning = ref(false)

// 初始化轮播图
const initCarousel = () => {
  if (!carouselRef.value) return

  // 获取轮播图容器宽度
  itemWidth.value = carouselRef.value.clientWidth

  // 设置初始位置
  moveTo(activeIndex.value, false)

  // 启动自动轮播
  startAutoPlay()
}

// 移动到指定索引
const moveTo = (index: number, withTransition = true) => {
  if (!carouselRef.value || isTransitioning.value) return

  // 处理边界情况
  if (index < 0) index = props.items.length - 1
  if (index >= props.items.length) index = 0

  // 更新活动状态
  const oldIndex = activeIndex.value
  activeIndex.value = index

  // 设置过渡效果
  const carouselInner = carouselRef.value.querySelector(".carousel-inner")
  if (carouselInner) {
    carouselInner.style.transition = withTransition
      ? "transform 0.5s ease"
      : "none"
    carouselInner.style.transform = `translateX(-${index * itemWidth.value}px)`
  }

  // 触发变更事件
  if (oldIndex !== index) {
    emit("change", index)
  }
}

// 下一张
const next = () => {
  if (isTransitioning.value) return
  moveTo(activeIndex.value + 1)
}

// 上一张
const prev = () => {
  if (isTransitioning.value) return
  moveTo(activeIndex.value - 1)
}

// 开始自动轮播
const startAutoPlay = () => {
  stopAutoPlay()

  if (props.items.length <= 1 || props.interval <= 0) return

  timer = setInterval(() => {
    next()
  }, props.interval)
}

// 停止自动轮播
const stopAutoPlay = () => {
  if (timer) {
    clearInterval(timer)
    timer = null
  }
}

// 处理过渡开始
const handleTransitionStart = () => {
  isTransitioning.value = true
}

// 处理过渡结束
const handleTransitionEnd = () => {
  isTransitioning.value = false
}

// 监听窗口大小变化
const handleResize = () => {
  if (!carouselRef.value) return

  // 重新计算宽度
  const newWidth = carouselRef.value.clientWidth
  if (newWidth !== itemWidth.value) {
    itemWidth.value = newWidth
    moveTo(activeIndex.value, false)
  }
}

// 生命周期钩子
onMounted(() => {
  nextTick(() => {
    initCarousel()

    // 添加事件监听
    window.addEventListener("resize", handleResize)
  })
})

onUnmounted(() => {
  stopAutoPlay()
  window.removeEventListener("resize", handleResize)
})
</script>

<template>
  <div class="carousel-container" ref="carouselRef">
    <!-- 轮播图内容 -->
    <div
      class="carousel-inner"
      @transitionstart="handleTransitionStart"
      @transitionend="handleTransitionEnd"
    >
      <div
        v-for="(item, index) in props.items"
        :key="item.id"
        class="carousel-item"
        :style="{ width: `${itemWidth}px` }"
      >
        <!-- 使用插槽自定义轮播项内容 -->
        <slot
          name="item"
          :item="item"
          :index="index"
          :active="index === activeIndex"
        >
          <!-- 默认内容，当没有提供插槽时显示 -->
          <img :src="item.imageUrl" alt="carousel" class="carousel-image" />

          <!-- 图片标题和描述（可选） -->
          <div v-if="item.title || item.description" class="carousel-caption">
            <h3 v-if="item.title" class="carousel-title">{{ item.title }}</h3>
            <p v-if="item.description" class="carousel-description">
              {{ item.description }}
            </p>
          </div>
        </slot>
      </div>
    </div>

    <!-- 指示器（椭圆点） -->
    <div
      v-if="props.showIndicators && props.items.length > 1"
      class="carousel-indicators"
      ref="indicatorsRef"
    >
      <button
        v-for="(item, index) in props.items"
        :key="item.id"
        :class="{ active: index === activeIndex }"
        @click="moveTo(index)"
        @mouseenter="stopAutoPlay"
        @mouseleave="startAutoPlay"
      ></button>
    </div>
  </div>
  <div class="footer-fff"></div>
</template>

<style scoped>
.carousel-container {
  position: relative;
  width: 100%;
  height: auto; /* 默认高度，可以根据需要调整 */
  overflow: hidden;
}

.carousel-inner {
  display: flex;
  height: 100%;
}

.carousel-item {
  flex-shrink: 0;
  height: 100%;
}

.carousel-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.carousel-caption {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  padding: 20px;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.7), transparent);
  color: white;
}

.carousel-title {
  margin: 0;
  font-size: 24px;
  font-weight: 500;
  margin-bottom: 8px;
}

.carousel-description {
  margin: 0;
  font-size: 16px;
  opacity: 0.9;
}

.carousel-control {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 40px;
  height: 40px;
  background-color: rgba(0, 0, 0, 0.3);
  color: white;
  border: none;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 10;
  transition: background-color 0.3s;
  font-size: 20px;
}

.carousel-control:hover {
  background-color: rgba(0, 0, 0, 0.6);
}

.prev {
  left: 15px;
}

.next {
  right: 15px;
}

.carousel-indicators {
  position: absolute;
  bottom: 58px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 8px;
  z-index: 10;
}

.carousel-indicators button {
  width: 12px;
  height: 9px;
  background: #ffffff;
  border-radius: 5px;
  border: none;
  cursor: pointer;
  transition: all 0.3s;
}

.carousel-indicators button.active {
  width: 36px;
  height: 9px;
  background: linear-gradient(135deg, #b866ff 0%, #ff669b 100%);
  border-radius: 5px;
}

.footer-fff {
  width: 100%;
  height: 76px;
  background: #ffffff;
  border-radius: 24px;
  backdrop-filter: blur(20px);
  margin-top: -26px;
}
</style>
